package com.h3c.ptability.task;

import cn.hutool.json.JSONUtil;
import com.eos.common.util.DateUtils;
import com.h3c.ptability.dto.eos.EosUserClientDTO;
import com.h3c.ptability.entity.PtDept;
import com.h3c.ptability.entity.PtManagementAll;
import com.h3c.ptability.mapper.PtDeptMapper;
import com.h3c.ptability.mapper.PtUserDeptMonthMapper;
import com.h3c.ptability.service.EosAuthService;
import com.h3c.ptability.service.IPtManagementAllService;
import com.h3c.ptability.service.IPtUserDeptMonthService;
import com.h3c.ptability.utils.AppBusinessException;
import com.h3c.ptability.utils.BusiEnumDefine;
import com.h3c.ptability.utils.CommonUtil;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author :h24002
 * @date :2023/3/7 19:06
 * @description :重置动态看板一二三级部门授权和相应角色名单
 */
@JobHandler(value = "resetDynamicBoardHandler")
@Component
@Slf4j
public class ResetDynamicBoardHandler extends IJobHandler {
    /**
     * 限制的主管类型（A0,90,80）
     */
    private List<String> ManageTypes;

    /**
     * 部门
     */
    @Resource
    private PtDeptMapper ptDeptMapper;

    /**
     * 主管
     */
    @Resource
    private IPtManagementAllService ptManagementAllService;

    /**
     * EOS相关接口
     */
    @Resource
    private EosAuthService eosAuthService;

    /**
     * 月度授权部门体系
     */
    @Resource
    private PtUserDeptMonthMapper ptUserDeptMonthMapper;
    /**
     * 月度授权部门体系
     */
    @Resource
    private IPtUserDeptMonthService ptUserDeptMonthService;

    /**
     * 开启定时任务
     *
     * @param param 掺入参数
     * @return 返回执行结果
     * @throws Exception 异常信息
     */
    @Override
    public ReturnT<String> execute(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, resetHrBudgetHandler.");
        XxlJobLogger.log("准备开始调用方法");

        Date date = new Date();
        executeJob(date);

        XxlJobLogger.log("调用结束");
        return SUCCESS;
    }

    /**
     * 定时执行重置 部门授权人员 月度部门数据
     *
     * @param date 要处理的日期
     */
    public void executeJob(Date date) {
        //月初第一天，重置上个月的授权数据，因为抓取的主管和部门数据是昨天的
        ManageTypes = Arrays.asList("A0", "90", "80");
        int days = DateUtils.getDate(date);
        if (days == 1) {
            Date dateNew = DateUtils.dateAddMonths(date, -1);
            executeHrDynamicJob(dateNew);
        }
        executeHrDynamicJob(date);
    }

    /**
     * 定时执行重置 部门授权人员 月度部门数据
     *
     * @param date 要处理的日期
     */
    private void executeHrDynamicJob(Date date) {
        //得到要处理的年月度：1号取值上个月，否则取值当前月
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMM");
        int dateMonth = Integer.parseInt(dateFormat.format(date));
        String hrDynamicBoardCadreBp = BusiEnumDefine.HR_DYNAMIC_BOARD_CADRE_BP;
        String hrDynamicBoardManage = BusiEnumDefine.HR_DYNAMIC_BOARD_MANAGE;
        String hrDynamicBoardMax = BusiEnumDefine.HR_DYNAMIC_BOARD_MAX;
        String hrDynamicBoardOther = BusiEnumDefine.HR_DYNAMIC_BOARD_OTHER;
        String hrDynamicAppId = BusiEnumDefine.HR_DYNAMIC_APP_ID;
        String opDesc = "[" + hrDynamicAppId + "-" + dateMonth + "]";
        try {
            //所有的部门授权用户列表
            List<String> eosUserList = new ArrayList<>();
            //所有需要补充自动授权部门授权用户列表
            List<String> autoUserList = new ArrayList<>();

            //第0步：清除无效部门数据：已失效部门
            Integer delCount = ptUserDeptMonthMapper.deletePtUserDeptMonth(hrDynamicAppId, dateMonth);
            XxlJobLogger.log("{}删除无效授权部门数据：{}", opDesc, delCount);

            //第0-1步：检查当前月是否有数据，没有数据，将上月数据进行复制到本月
            String initMsg = ptUserDeptMonthService.initPtUserDeptMonth(dateMonth, hrDynamicAppId);
            XxlJobLogger.log("{}{}", opDesc, initMsg);

            //第1步：抓取基础部门数据
            List<PtDept> ptDeptList = ptUserDeptMonthService.getPtDeptList();
            //第1.1步：获取部门主管数据(限一级正副、二级正)，构建一二级部门主管角色用户列表
            List<PtDept> deptManagerList = ptManagementAllService.selectListByPostTypeCodes(ManageTypes, true, null);
            XxlJobLogger.log("{}摘选部门主管范围是{},数据量为{}", opDesc, String.join(",", ManageTypes), deptManagerList.size());

            //第1.2步：获取BP和干部部相关角色人员数据
            List<EosUserClientDTO> eosCadreBpList = eosAuthService.getUserListByRoleCode(hrDynamicBoardCadreBp, hrDynamicAppId, 1, 10000);
            if (!CollectionUtils.isEmpty(eosCadreBpList)) {
                List<String> list = eosCadreBpList.stream()
                        .map(EosUserClientDTO::getEmpCode)
                        .filter(StringUtils::hasText)
                        .distinct().collect(Collectors.toList());
                eosUserList.addAll(list);
            }

            //第1.3步：获取专业人员相关角色人员数据
            List<EosUserClientDTO> eosMaxList = eosAuthService.getUserListByRoleCode(hrDynamicBoardMax, hrDynamicAppId, 1, 10000);
            if (!CollectionUtils.isEmpty(eosMaxList)) {
                //补充招聘调配部角色人员
                List<String> list = eosMaxList.stream()
                        .map(EosUserClientDTO::getEmpCode)
                        .filter(StringUtils::hasText)
                        .distinct().collect(Collectors.toList());
                String topUserMsg = ptUserDeptMonthService.replenishTopUserDeptMonth(dateMonth, hrDynamicAppId, ptDeptList, list);
                XxlJobLogger.log("{}{}", opDesc, topUserMsg);
                eosUserList.addAll(list);
                autoUserList.addAll(list);
            }

            //第1.4步：获取其他角色人员数据
            List<EosUserClientDTO> eosHrList = eosAuthService.getUserListByRoleCode(hrDynamicBoardOther, hrDynamicAppId, 1, 10000);
            if (!CollectionUtils.isEmpty(eosHrList)) {
                List<String> list = eosHrList.stream()
                        .map(EosUserClientDTO::getEmpCode)
                        .filter(StringUtils::hasText)
                        .distinct().collect(Collectors.toList());
                eosUserList.addAll(list);
            }

            //第2步：重置自动授权主管的授权部门信息
            String deptManageMsg = ptUserDeptMonthService.replenishManageDeptManageMonth(dateMonth, hrDynamicAppId, eosUserList, deptManagerList);
            XxlJobLogger.log("{}{}", opDesc, deptManageMsg);

            //第3.2步：汇总所有部门授权角色的人员列表
            if (!CollectionUtils.isEmpty(deptManagerList)) {
                //补充招聘调配部角色人员
                List<String> deptManagerIds = CommonUtil.getDeptManagerIds(deptManagerList);
                deptManagerIds = deptManagerIds.stream().filter(o -> !eosUserList.contains(o)).distinct().collect(Collectors.toList());
                //第3.1步：将查询到的部门主管数据插入到相应角色中：重置数据
                String manageMsg = ptUserDeptMonthService.resetDeptManage(hrDynamicBoardManage, hrDynamicAppId, deptManagerIds);
                XxlJobLogger.log("{}{}", opDesc, manageMsg);

                eosUserList.addAll(deptManagerIds);
                autoUserList.addAll(deptManagerIds);
            }
            //自动补充需要补充授权部门授权用户列表
            autoUserList = autoUserList.stream().distinct().collect(Collectors.toList());
            XxlJobLogger.log("{} {} 所有需要补充自动授权部门授权用户列表：{}", opDesc, dateMonth, JSONUtil.toJsonStr(autoUserList));
            ptUserDeptMonthService.modifyUserDeptMonth(dateMonth, hrDynamicAppId, ptDeptList, autoUserList);
        } catch (Exception ex) {
            XxlJobLogger.log("{} {} 数据异常：{}", opDesc, dateMonth, JSONUtil.toJsonStr(ex));
            log.error("{}定时执行重置部门授权人员月度部门数据 {} 数据异常：{}", opDesc, dateMonth, JSONUtil.toJsonStr(ex));
            throw new AppBusinessException(String.format("%s 定时执行重置部门授权人员月度部门数据 %s 异常：%s", opDesc, dateMonth, ex.getMessage()));
        }
    }


}
